package com.qm.console.service.user.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonObject;
import com.qm.console.component.exception.BusinessException;
import com.qm.console.component.util.DateUtil;
import com.qm.console.component.util.HttpInvokeUtil;
import com.qm.console.component.util.TimeUtils;
import com.qm.console.controller.dto.BaseDO;
import com.qm.console.controller.dto.BaseRsp;
import com.qm.console.controller.dto.ResultEnum;
import com.qm.console.dao.mapper.*;
import com.qm.console.dao.model.*;
import com.qm.console.pubdef.constant.UrlConstant;
import com.qm.console.pubdef.dto.anchor.ImMsgQueryDTO;
import com.qm.console.pubdef.dto.anchor.UserActionDTO;
import com.qm.console.pubdef.dto.user.*;
import com.qm.console.service.analysis.AnalysisService;
import com.qm.console.service.user.UserService;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {
    private final String accountAdminUrl="/user";

    @Autowired
    private PropChangeDOMapper propChangeDOMapper;
    @Autowired
    private ValueDisplayConfigMapper propReasonDOMapper;
    @Autowired
    private DateUtil dateUtil;
    @Autowired
    private AnalysisService analysisService;
    @Autowired
    private AccountRegisterDOMapper accountRegisterDOMapper;

    @Override
    public BaseRsp listChannelAdmin(Map<String,String> paramMap){
        String url= UrlConstant.ApiServerHost+accountAdminUrl+"/channel/list";
        String body= HttpInvokeUtil.httpGet(url,paramMap, null);
        BaseRsp rsp= JSONObject.parseObject(body,BaseRsp.class);
        return  rsp;
    }

    @Override
    public BaseRsp listUserAdmin(Map<String,String> paramMap){
        String url= UrlConstant.ApiServerHost+accountAdminUrl+"/list";
        String body= HttpInvokeUtil.httpGet(url,paramMap, null);
        JSONObject jsonRes= JSONObject.parseObject(body);
        List<String> userIds = new ArrayList<>();
        JSONObject jsonData = (JSONObject) jsonRes.get("data");
//        data.put("total", data.getInteger("total") - nums);
        JSONArray jsonList = (JSONArray) jsonData.get("list");
        for (int i = jsonList.size() - 1; i >= 0; i--) {
            JSONObject item = jsonList.getJSONObject(i);
            userIds.add(item.getInteger("id").toString());
        }
        BaseRsp rsp=JSONObject.parseObject(jsonRes.toJSONString(), BaseRsp.class);
        return rsp;
    }

    @Override
    public BaseRsp userDetailAdmin(Map<String,String> paramMap){
        String url= UrlConstant.ApiServerHost+accountAdminUrl+"/detail/"+paramMap.get("userId");
        String body= HttpInvokeUtil.httpGet(url,paramMap, null);
        JSONObject jsonRes= JSONObject.parseObject(body);
        AccountRegisterDO userInfo = accountRegisterDOMapper.selectByPrimaryKey(Integer.valueOf(paramMap.get("userId")));
        if (userInfo != null){
            JSONObject repData = jsonRes.getJSONObject("data");
            repData.put("version", userInfo.getAppVersion());
        }
        BaseRsp rsp=JSONObject.parseObject(jsonRes.toJSONString(), BaseRsp.class);
        return rsp;
    }

    @Override
    public BaseDO supplementList(Map<String,Object> paramMap){
        String url= UrlConstant.ApiServerHost+"/add/order/list";

        // 处理paramMap，字符串化
        Map<String, String> param = new HashMap<>();
        for (Map.Entry<String, Object> entry : paramMap.entrySet()) {
            if (entry.getValue() == null){
                param.put(entry.getKey(), null);
            }
            else {
                param.put(entry.getKey(), entry.getValue().toString());
            }
        }

        // 请求接口获取响应
        String body= HttpInvokeUtil.httpGet(url,param, null);

        // 响应数据格式化处理
        JSONObject rep = JSONObject.parseObject(body);
        JSONObject data = rep.getJSONObject("data");
        JSONArray addOrderInfoList = data.getJSONArray("addOrderInfoList");
        for( int i=0; i<addOrderInfoList.size(); i++){
            JSONObject ob = addOrderInfoList.getJSONObject(i);
            Long createTime = ob.getLong("createTimestamp");
            Long updateTime = ob.getLong("updateTimestamp");

            String createTimestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(createTime);
            String updateTimestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(updateTime);

            ob.put("createTime", createTimestamp);
            ob.put("updateTime", updateTimestamp);
            ob.remove("createTimestamp");
            ob.remove("updateTimestamp");

            String orderId = ob.get("orderId").toString();
            ob.put("orderId", orderId);

        }

        return JSONObject.parseObject(rep.toJSONString(),BaseDO.class);
    }

    @Override
    public BaseRsp supplementAdd(SupplementDTO params){
        Map paramMap= new HashMap<>();
        Integer giftId=params.getGiftId();
        paramMap.put("giftId",giftId);
        Integer num=params.getNum();
        paramMap.put("num",num);
        Integer type=params.getType();
        paramMap.put("type",type);
        String note=params.getNote();
        paramMap.put("note",note);
        List<Integer> userIds=params.getUserIds();
        paramMap.put("userIds",userIds);

        String req = JSONObject.toJSONString(paramMap);
        String url= UrlConstant.ApiServerHost+"/add/order/new";
        String body= HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp= JSONObject.parseObject(body, BaseRsp.class);
        return  rsp;
    }

    @Override
    public BaseRsp supplementDispose(SupplementDisposeDTO params){
        Map paramMap= new HashMap<>();
        Integer operateType=params.getOperateType();
        paramMap.put("operateType",operateType);
        List<Long> orderIds=params.getOrderIds();
        paramMap.put("orderIds",orderIds);

        String req = JSONObject.toJSONString(paramMap);
        String url= UrlConstant.ApiServerHost+"/add/order/operate";
        String body= HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp= JSONObject.parseObject(body, BaseRsp.class);
        return  rsp;
    }

    @Override
    public BaseDO<AnchorDetailDTO> anchorDetail(Map<String, String> paramMap){
        String url= UrlConstant.ApiServerHost+"/user/statistical/detail";
        // 请求接口获取响应
        String body= HttpInvokeUtil.httpGet(url,paramMap, null);
        BaseDO<AnchorDetailDTO> rsp= JSONObject.parseObject(body, BaseDO.class);
        return rsp;
    }

    @Override
    public BaseDO<AccuseInfoDTO> accuseList(Map<String, String> paramMap){
        String url= UrlConstant.ApiServerHost+"/user/report/list";
        // 请求接口获取响应
        String body= HttpInvokeUtil.httpGet(url,paramMap, null);

        JSONObject res = JSONObject.parseObject(body);
        BaseDO rsp= JSONObject.parseObject(res.toJSONString(), BaseDO.class);
        return  rsp;
    }

    @Override
    public BaseRsp accuseDispose(AccuseDisposeDTO params){
        String url= UrlConstant.ApiServerHost+"/user/report/reply";
        String req = JSONObject.toJSONString(params);
        String body= HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);
        BaseRsp rsp= JSONObject.parseObject(body, BaseRsp.class);
        return  rsp;
    }


    @Override
    public BaseRsp orderList(Map<String, String> paramMap){
        String url= UrlConstant.ApiServerHost+"/user/recharge_order_list";

//        JSONObject chargeUnit=JSONObject.parseObject(paramMap.get("chargeUnit"));

        Map<String, Object> params = new HashMap<>();
        Map<String, Object> pageQuery = new HashMap<>();
        Map<String, Object> domainRechargeVo = new HashMap<>();

        pageQuery.put("pageNum", paramMap.get("pageNum"));
        pageQuery.put("pageSize", paramMap.get("pageSize"));

        params.put("pageQuery", pageQuery);
        if (paramMap.get("rechargeName") != null && paramMap.get("rechargeName") != "") {
            domainRechargeVo.put("rechargeId", paramMap.get("rechargeId"));
            domainRechargeVo.put("rechargeType", paramMap.get("rechargeType"));
            params.put("domainRechargeVo", domainRechargeVo);
        }
        if (paramMap.get("endTime") != null && paramMap.get("startTime") != null) {
            params.put("endTime", paramMap.get("endTime"));
            params.put("startTime", paramMap.get("startTime"));
        }
        if (paramMap.get("nickname") != null && paramMap.get("nickname") != "") {
            params.put("nickName", paramMap.get("nickname"));
        }
        if (paramMap.get("payChannel") != null && paramMap.get("payChannel") != "") {
            params.put("payChannelType", paramMap.get("payChannel"));
        }
        if (paramMap.get("payStatus") != null && paramMap.get("payStatus") != "") {
            params.put("payStatus", paramMap.get("payStatus"));
        }
        if (paramMap.get("registerChannel") != null && paramMap.get("registerChannel") != "") {
            params.put("registerChannel", paramMap.get("registerChannel"));
        }
        if (paramMap.get("userId") != null && paramMap.get("userId") != "") {
            params.put("userId", paramMap.get("userId"));
        }
        if (paramMap.get("countryCode") != null && paramMap.get("countryCode") != "") {
            params.put("countryCode", paramMap.get("countryCode"));
        }
        String req = JSONObject.toJSONString(params);
        String body= HttpInvokeUtil.httpPostJson(url, req, UrlConstant.DefaultEncode, null);

        // 响应数据格式化处理
        JSONObject rep = JSONObject.parseObject(body);
//        JSONObject data = rep.getJSONObject("data");
//        JSONArray rechargeOrderList = data.getJSONArray("rechargeOrderList");
//        for( int i=0; i<rechargeOrderList.size(); i++){
//            JSONObject ob = rechargeOrderList.getJSONObject(i);
//            Long orderPayTimestamp = ob.getLong("orderPayTime");
//            Long orderCreateTimestamp = ob.getLong("orderCreateTime");
//
//            if (orderPayTimestamp != null) {
//                String orderPayTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(orderPayTimestamp);
//                ob.put("orderPayTime", orderPayTime);
//            }
//            if (orderCreateTimestamp != null) {
//                String orderCreateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(orderCreateTimestamp);
//                ob.put("orderCreateTime", orderCreateTime);
//            }
//        }

        BaseRsp rsp= JSONObject.parseObject(rep.toJSONString(), BaseRsp.class);
        return  rsp;
    }

    @Override
    public BaseRsp chargeUnitList(){
        String url= UrlConstant.ApiServerHost+"/user/recharge_list";
        String body= HttpInvokeUtil.httpGet(url, null, null);
        BaseRsp rsp= JSONObject.parseObject(body, BaseRsp.class);
        return rsp;
    }


//    ----------------- prop -------------------

    @Override
    public BaseRsp listPropChanges(PropChangeQueryDTO query) {
        if (query.getOffset() == null || query.getLimit() == null) {
            throw new BusinessException(ResultEnum.PARA_ERR);
        }
        if (query.getPropType() != null) {
            query.setPropTypes(Arrays.asList(query.getPropType().split(",")));
        }
        if (query.getReason() != null) {
            query.setReasons(Arrays.asList(query.getReason().split(",")));
        }
        Date startTime;
        Date endTime;
        Date minTime = new Date(2020 - 1900, Calendar.JULY, 1);
        Date maxTime = new Date();
        if (query.getStartTime() == null) {
            startTime = minTime;
        } else {
            startTime = TimeUtils.parse(query.getStartTime(), TimeUtils.DATE_FORMAT_DATE_D);
            if (startTime.getTime() < minTime.getTime()) {
                startTime = minTime;
            }
        }
        if (query.getEndTime() == null) {
            endTime = maxTime;
        } else {
            endTime = TimeUtils.parse(query.getEndTime(), TimeUtils.DATE_FORMAT_DATE_D);
            if (endTime.getTime() > maxTime.getTime()) {
                endTime = maxTime;
            }
        }
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);

        List<String> tables = months.stream().map(month -> "prop_change_" + month).collect(Collectors.toList());
        query.setTables(tables);
        if (tables.isEmpty()) {
            return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", Collections.emptyList(), "count", 0));
        }

        List<TableCountDO> counts = propChangeDOMapper.count(query);

        Collections.reverse(counts);

        final List<String> contentTables = new ArrayList<>();
        int totalCount = 0;
        int realOffset = 0;
        boolean started = false;
        for (TableCountDO count : counts) {
            if (query.getOffset() >= totalCount && query.getOffset() < totalCount + count.getTotal()) {
                //临界条件..
                contentTables.add(count.getTableName());
                realOffset = query.getOffset() - totalCount;
                started = true;
            } else if (started && query.getOffset() + query.getLimit() >= totalCount) {
                contentTables.add(count.getTableName());
            }
            totalCount += count.getTotal();
        }
        if (contentTables.isEmpty()) {
            return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", Collections.emptyList(), "count", 0));
        }
        query.setOffset(realOffset);
        query.setTables(contentTables);
        List<PropChangeDO> list = propChangeDOMapper.list(query);
        List<ValueDisplayConfig> reasons = listPropReasons();
        List<ValueDisplayConfig> types = listPropTypes();
        Map<String, String> reasonMap = reasons.stream().collect(Collectors.toMap(ValueDisplayConfig::getValue, ValueDisplayConfig::getLabel));
        Map<String, String> typeMap = types.stream().collect(Collectors.toMap(ValueDisplayConfig::getValue, ValueDisplayConfig::getLabel));
        list.forEach(item -> {
            item.setChangeReason(reasonMap.getOrDefault(item.getChangeReason(), item.getChangeReason()));
            item.setPropType(typeMap.getOrDefault(item.getPropType(), item.getPropType()));
        });
        return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", list, "count", totalCount));
    }

    @Override
    public BaseRsp propChangeCount(PropChangeQueryDTO query) {
        if (query.getOffset() == null || query.getLimit() == null) {
            throw new BusinessException(ResultEnum.PARA_ERR);
        }
        if (query.getPropType() != null) {
            query.setPropTypes(Arrays.asList(query.getPropType().split(",")));
        }
        Date startTime;
        Date endTime;
        Date minTime = new Date(2020 - 1900, Calendar.JULY, 1);
        Date maxTime = new Date();
        if (query.getStartTime() == null) {
            startTime = minTime;
        } else {
            startTime = TimeUtils.parse(query.getStartTime(), TimeUtils.DATE_FORMAT_DATE_D);
            if (startTime.getTime() < minTime.getTime()) {
                startTime = minTime;
            }
        }
        if (query.getEndTime() == null) {
            endTime = maxTime;
        } else {
            endTime = TimeUtils.parse(query.getEndTime(), TimeUtils.DATE_FORMAT_DATE_D);
            if (endTime.getTime() > maxTime.getTime()) {
                endTime = maxTime;
            }
        }
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);

        List<String> tables = months.stream().map(month -> "prop_change_" + month).collect(Collectors.toList());
        query.setTables(tables);
        if (tables.isEmpty()) {
            return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", Collections.emptyList(), "count", 0));
        }

        Integer totalCount = propChangeDOMapper.targetUserChangeCount(query);

        List<PropChangeDO> list = propChangeDOMapper.targetUserChangeList(query);

        return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", list, "count", totalCount));
    }

    @Override
    public List<ValueDisplayConfig> listPropReasons() {
        return propReasonDOMapper.list(ValueDisplayConfig.VALUE_TYPE_PROP_CHANGE_REASON);
    }

    @Override
    public void PropChangeValue(ValueDisplayConfig query) {
        propReasonDOMapper.updateByPrimaryKeySelective(query);
    }

    @Override
    public List<Map<String, String>> listPropChannels() {
        return analysisService.getChannels();
    }

    @Override
    public List<ValueDisplayConfig> listPropTypes() {
        return propReasonDOMapper.list(ValueDisplayConfig.VALUE_TYPE_PROP);
    }

    @Override
    public BaseRsp userProp(PropChangeQueryDTO query) {
        Date startTime = new Date(2020 - 1900, Calendar.JULY, 1);
        Date endTime = new Date();
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);

        List<String> tables = months.stream().map(month -> "prop_change_" + month).collect(Collectors.toList());
        query.setTables(tables);

        // 试聊卡总获得数量
        List<String> cardsReasons = Arrays.asList("ACD_TASK_USER_COMPL", "ACD_RECHARGE_PREFERENTIAL", "ACD_ADD_ORDER", "ACD_ACTIVITY_DRAW", "ACD_GREENHAND_INVITE");
        query.setPropTypes(Arrays.asList("试聊卡"));
        query.setReasons(cardsReasons);
        List<TableCountDO> cards = propChangeDOMapper.getChange(query);
        int cardTotal = 0;
        for (TableCountDO item : cards) {
            cardTotal = cardTotal + item.getTotal();
        };

        // 私聊券总获得数量
        List<String> ticketReasons = Arrays.asList("ACT_MESSAGE", "ACT_ADD_ORDER", "ACT_RECHARGE_PREFERENTIAL", "ACT_ACTIVITY_DRAW", "ACT_SIGN_WEEKLY");
        query.setPropTypes(Arrays.asList("私聊券"));
        query.setReasons(ticketReasons);
        List<TableCountDO> tickets = propChangeDOMapper.getChange(query);
        int ticketTotal = 0;
        for (TableCountDO item : tickets) {
            ticketTotal = ticketTotal + item.getTotal();
        };

        return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of( "cardTotal", cardTotal, "ticketTotal", ticketTotal));
    }

    @Override
    public BaseRsp userRecharge(PropChangeQueryDTO query) {
        Date startTime = new Date(2020 - 1900, Calendar.JULY, 1);
        Date endTime = new Date();
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);

        List<String> tables = months.stream().map(month -> "prop_change_" + month).collect(Collectors.toList());
        query.setTables(tables);

        // 钻石总获得数量
        query.setPropTypes(Arrays.asList("钻石"));
        query.setReasons(Arrays.asList("AD_RECHARGE_PREFERENTIAL", "AD_RECHARGE_CARD","AD_RECHARGE_CARD_DAILY_REWARD",
                "AD_RECHARGE_DIRECT", "AD_COIN_EXCHANGE", "AD_RECHARGE_TASK", "AD_ADD_ORDER", "AD_ACTIVITY_DRAW",
                "AD_ACTIVITY_BOX", "AD_SIGN_WEEKLY", "AD_LUCK_GIFT_DRAW", "AD_LIMIT_RECHARGE"));
        List<TableCountDO> totalGet = propChangeDOMapper.getChange(query);
        int diamondTotal = 0;
        for (TableCountDO item : totalGet) {
            diamondTotal = diamondTotal + item.getTotal();
        };

        // 钻石累计消耗
        query.setReasons(Arrays.asList("MD_VOICE_CHAT", "MD_POUND_EGG", "MD_VIDEO_CHAT", "MD_SEND_GIFT",
                "MD_IM_MESSAGE", "MD_UPDATE_NICKNAME","MD_ADD_ORDER", "MD_ACTIVITY_LUKY_DRAW", "MD_ACTIVITY_LUCK_DRAW"));
        List<TableCountDO> consumes = propChangeDOMapper.getChange(query);
        int diamondConsume = 0;
        for (TableCountDO item : consumes) {
            diamondConsume = diamondConsume + item.getTotal();
        };

        // 钻石聊天消耗消耗
        query.setReasons(Arrays.asList("MD_IM_MESSAGE"));
        List<TableCountDO> chatConsumeList = propChangeDOMapper.getChange(query);
        int chatConsume = 0;
        for (TableCountDO item : chatConsumeList) {
            chatConsume = chatConsume + item.getTotal();
        };

        // 钻石语音消耗消耗
        query.setReasons(Arrays.asList("MD_VOICE_CHAT"));
        List<TableCountDO> voiceConsumeList = propChangeDOMapper.getChange(query);
        int voiceConsume = 0;
        for (TableCountDO item : voiceConsumeList) {
            voiceConsume = voiceConsume + item.getTotal();
        };

        // 钻石视频消耗消耗
        query.setReasons(Arrays.asList("MD_VIDEO_CHAT"));
        List<TableCountDO> videoConsumeList = propChangeDOMapper.getChange(query);
        int videoConsume = 0;
        for (TableCountDO item : videoConsumeList) {
            videoConsume = videoConsume + item.getTotal();
        };

        // 钻石礼物消耗消耗
        query.setReasons(Arrays.asList("MD_SEND_GIFT"));
        List<TableCountDO> giftConsumeList = propChangeDOMapper.getChange(query);
        int giftConsume = 0;
        for (TableCountDO item : giftConsumeList) {
            giftConsume = giftConsume + item.getTotal();
        };

        return new BaseRsp(ResultEnum.SUCCESS, new ImmutableMap.Builder<String, Integer>().
                put( "diamondTotal", diamondTotal).
                put("diamondConsume", diamondConsume).
                put("chatConsume", chatConsume).
                put("voiceConsume", voiceConsume).
                put("videoConsume", videoConsume).
                put("giftConsume", giftConsume).
                build()
        );
    }

    @Override
    public BaseRsp userWithdraw(PropChangeQueryDTO query) {
        Date startTime = new Date(2020 - 1900, Calendar.JULY, 1);
        Date endTime = new Date();
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);

        List<String> tables = months.stream().map(month -> "prop_change_" + month).collect(Collectors.toList());
        query.setTables(tables);

        // 总获得数量
        query.setPropTypes(Arrays.asList("积分", "积分+"));
        query.setReasons(Arrays.asList("AC_IM_MESSAGE", "AC_VOICE_CHAT", "AC_VIDEO_CHAT", "AC_RECEIVE_GIFT", "AC_INVITE_USER",
                "AC_FIRST_APPRENTICESHIP", "AC_FIRST_APPRENTICESHIP_UNITE", "AC_TASK_USER_COMPL",
                "AC_ADD_ORDER", "AC_DAILY_TASK_USER_COMPLETE", "AC_RECEIVE_GIFT_DIAMONDS", "AC_RECEIVE_GIFT_PACKAGE",
                "AC_WEEKLY_TASK_USER_COMPLETE", "AC_ACTIVITY_NEW_YEAR_TASK", "AC_REGISTER_ACCOST_RED_COINS"));
        List<TableCountDO> totalGet = propChangeDOMapper.getChange(query);
        int scoreTotal = 0;
        for (TableCountDO item : totalGet) {
            scoreTotal = scoreTotal + item.getTotal();
        };

        // 累计消耗
        query.setReasons(Arrays.asList("MC_EXCHANGE_DIAMOND", "MC_WITHDRAW", "MC_ADD_ORDER"));
        List<TableCountDO> consumes = propChangeDOMapper.getChange(query);
        int scoreConsume = 0;
        for (TableCountDO item : consumes) {
            scoreConsume = scoreConsume + item.getTotal();
        };

        // 文字聊天
        query.setReasons(Arrays.asList("AC_IM_MESSAGE"));
        List<TableCountDO> chatConsumeList = propChangeDOMapper.getChange(query);
        int chatConsume = 0;
        for (TableCountDO item : chatConsumeList) {
            chatConsume = chatConsume + item.getTotal();
        };

        // 语音聊天
        query.setReasons(Arrays.asList("AC_VOICE_CHAT"));
        List<TableCountDO> voiceConsumeList = propChangeDOMapper.getChange(query);
        int voiceConsume = 0;
        for (TableCountDO item : voiceConsumeList) {
            voiceConsume = voiceConsume + item.getTotal();
        };

        // 视频聊天
        query.setReasons(Arrays.asList("AC_VIDEO_CHAT"));
        List<TableCountDO> videoConsumeList = propChangeDOMapper.getChange(query);
        int videoConsume = 0;
        for (TableCountDO item : videoConsumeList) {
            videoConsume = videoConsume + item.getTotal();
        };

        // 礼物
        query.setReasons(Arrays.asList("AC_RECEIVE_GIFT", "AC_RECEIVE_GIFT_DIAMONDS", "AC_RECEIVE_GIFT_PACKAGE"));
        List<TableCountDO> giftConsumeList = propChangeDOMapper.getChange(query);
        int giftConsume = 0;
        for (TableCountDO item : giftConsumeList) {
            giftConsume = giftConsume + item.getTotal();
        };

        // 收徒奖励
        query.setReasons(Arrays.asList("AC_INVITE_USER"));
        List<TableCountDO> divideConsumeList = propChangeDOMapper.getChange(query);
        int divideConsume = 0;
        for (TableCountDO item : divideConsumeList) {
            divideConsume = divideConsume + item.getTotal();
        };

        // 收徒分成
        query.setReasons(Arrays.asList("AC_FIRST_APPRENTICESHIP", "AC_FIRST_APPRENTICESHIP_UNITE"));
        List<TableCountDO> prenticeConsumeList = propChangeDOMapper.getChange(query);
        int prenticeConsume = 0;
        for (TableCountDO item : prenticeConsumeList) {
            prenticeConsume = prenticeConsume + item.getTotal();
        };

        return new BaseRsp(ResultEnum.SUCCESS, new ImmutableMap.Builder<String, Integer>().
                put( "scoreTotal", scoreTotal).
                put("scoreConsume", scoreConsume).
                put("chatConsume", chatConsume).
                put("voiceConsume", voiceConsume).
                put("videoConsume", videoConsume).
                put("giftConsume", giftConsume).
                put("divideConsume", divideConsume).
                put("prenticeConsume", prenticeConsume).
                build()
        );
    }

    @Autowired
    private UserActionDOMapper userActionDOMapper;

    @Override
    public BaseRsp userAction(UserActionDTO query) {
        if (query.getOffset() == null || query.getLimit() == null) {
            throw new BusinessException(ResultEnum.PARA_ERR);
        }

        Date startTime;
        Date endTime;
        Date minTime = new Date(2021 - 1900, Calendar.MARCH, 1);
        Date maxTime = new Date();
        if (query.getStartTime() == null) {
            startTime = minTime;
        } else {
            startTime = TimeUtils.parse(query.getStartTime(), TimeUtils.DATE_FORMAT_DATE_D);
            if (startTime.getTime() < minTime.getTime()) {
                startTime = minTime;
            }
        }
        if (query.getEndTime() == null) {
            endTime = maxTime;
        } else {
            endTime = TimeUtils.parse(query.getEndTime(), TimeUtils.DATE_FORMAT_DATE_D);
            if (endTime.getTime() > maxTime.getTime()) {
                endTime = maxTime;
            }
        }
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);

        List<String> tables = months.stream().map(month -> "user_action_" + month).collect(Collectors.toList());
        query.setTables(tables);
        if (tables.isEmpty()) {
            return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", Collections.emptyList(), "count", 0));
        }
        List<TableCountDO> counts = userActionDOMapper.total(query);

        Collections.reverse(counts);

        final List<String> contentTables = new ArrayList<>();
        int totalCount = 0;
        int realOffset = 0;
        boolean started = false;
        for (TableCountDO count : counts) {
            if (query.getOffset() >= totalCount && query.getOffset() < totalCount + count.getTotal()) {
                //临界条件..
                contentTables.add(count.getTableName());
                realOffset = query.getOffset() - totalCount;
                started = true;
            } else if (started && query.getOffset() + query.getLimit() >= totalCount) {
                contentTables.add(count.getTableName());
            }
            totalCount += count.getTotal();
        }
        if (contentTables.isEmpty()) {
            return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of("list", Collections.emptyList(), "count", 0));
        }
        query.setOffset(realOffset);
        query.setTables(contentTables);
        List<UserActionDO> list = userActionDOMapper.list(query);

        return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of( "list", list, "total", totalCount));
    }

    @Autowired
    private ImMsgDOMapper imMsgDOMapper;
    @Autowired
    private CharRecordDOMapper charRecordDOMapper;
    @Autowired
    private ChatRecordDOMapper chatRecordDOMapper;


    @Override
    public BaseRsp userChatGift(ImMsgQueryDTO paramMap) {
        Date startTime = new Date(2020 - 1900, Calendar.JULY, 1);
        Date endTime = new Date();
        Calendar startTimeC = Calendar.getInstance();
        startTimeC.setTime(startTime);
        Calendar endTimeC = Calendar.getInstance();
        endTimeC.setTime(endTime);
        List<String> months = dateUtil.listMonths(startTimeC, endTimeC);
        List<String> tables = months.stream().map(month -> "immsg_" + month).collect(Collectors.toList());
        paramMap.setTables(tables);

        CharRecordDO chatParams = new CharRecordDO();
        chatParams.setFromUser(paramMap.getUserId());
        chatParams.setToUser(paramMap.getUserId());
//        chatParams.setValid(true);

        SimpleDateFormat date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 语音时长
        Long voiceTime = 0L;
        chatParams.setChatType(1);
//        System.out.println("==========");
//        System.out.println(chatParams.toString());
        List<CharRecordDO> voiceList = charRecordDOMapper.list(chatParams);
        for(CharRecordDO voice: voiceList) {
            if (voice.getAcceptTime() != null && voice.getValid() && voice.getEndTime() != null){
//                System.out.println(voice.getId());
                Long tmpTime = dateUtil.DateToTimestamp(date.format(voice.getEndTime())) - dateUtil.DateToTimestamp(date.format(voice.getAcceptTime()));
                voiceTime = voiceTime + tmpTime;
            }
        };
        // 视频时长
        Long videoTime = 0L;
        chatParams.setChatType(0);
        List<CharRecordDO> videoList = charRecordDOMapper.list(chatParams);
        for(CharRecordDO video: videoList) {
            if (video.getAcceptTime() != null && video.getValid() && video.getEndTime() != null){
                Long tmpTime = dateUtil.DateToTimestamp(date.format(video.getEndTime())) - dateUtil.DateToTimestamp(date.format(video.getAcceptTime()));
                videoTime = videoTime + tmpTime;
            }
        };
        // 语音接通次数
        chatParams.setChatType(1);
        chatParams.setStates(Arrays.asList(0, 1, 2));
        int voiceConnTimes = charRecordDOMapper.count(chatParams);
        // 视频接通次数
        chatParams.setChatType(0);
        int videoConnTimes = charRecordDOMapper.count(chatParams);
        // 语音接通人数
        chatParams.setChatType(1);
        Set<Integer> userSet = new HashSet<>();
        List<CharRecordDO> voiceConnList = charRecordDOMapper.countUser(chatParams);
        for(CharRecordDO item: voiceConnList) {
            userSet.add(item.getFromUser());
            if (item.getToUser() != null){
                userSet.add(item.getToUser());
            }
        }
        int voiceConnUsers = userSet.size() - 1;
        // 视频接通人数
        chatParams.setChatType(0);
        Set<Integer> userSetVideo = new HashSet<>();
        List<CharRecordDO> videoConnList = charRecordDOMapper.countUser(chatParams);
        for(CharRecordDO item: videoConnList) {
            userSetVideo.add(item.getFromUser());
            if (item.getToUser() != null){
                userSetVideo.add(item.getToUser());
            }
        }
        int videoConnUsers = userSet.size() - 1;

        chatParams.setStates(null);
        // 语音被叫次数
        chatParams.setChatType(1);
        chatParams.setFromUser(null);
        int voiceGetTimes = charRecordDOMapper.count(chatParams);
        // 视频被叫次数
        chatParams.setChatType(0);
        int videoGetTimes = charRecordDOMapper.count(chatParams);
        // 语音被叫人数
        chatParams.setChatType(1);
        Set<Integer> getCallSet = new HashSet<>();
        List<CharRecordDO> voiceGetList = charRecordDOMapper.countUser(chatParams);
        for(CharRecordDO item: voiceGetList) {
            getCallSet.add(item.getFromUser());
        }
        int voiceGetUsers = getCallSet.size() - 1;
        // 视频被叫人数
        chatParams.setChatType(0);
        Set<Integer> getCallSetVideo = new HashSet<>();
        List<CharRecordDO> videoGetList = charRecordDOMapper.countUser(chatParams);
        for(CharRecordDO item: videoGetList) {
            getCallSetVideo.add(item.getFromUser());
        }
        int videoGetUsers = getCallSet.size() - 1;
        // 主动语音次数
        chatParams.setChatType(1);
        chatParams.setFromUser(paramMap.getUserId());
        chatParams.setToUser(null);
        int voiceSendTimes = charRecordDOMapper.count(chatParams);
        // 主动视频次数
        chatParams.setChatType(0);
        int videoSendTimes = charRecordDOMapper.count(chatParams);
        // 主动语音接通次数
        chatParams.setChatType(1);
        chatParams.setStates(Arrays.asList(0, 1, 2));
        int voiceSendConn = charRecordDOMapper.count(chatParams);
        // 主动视频接通次数
        chatParams.setChatType(1);
        int videoSendConn = charRecordDOMapper.count(chatParams);

        // 主动打招呼次数
        paramMap.setMsgType("11");
        int hiTimes = 0;
        List<TableCountDO> hiList = imMsgDOMapper.count(paramMap);
        for (TableCountDO item: hiList){
            hiTimes = hiTimes + item.getTotal();
        }
        // 收礼次数
        paramMap.setSecondUserId(paramMap.getUserId());
        paramMap.setUserId(null);
        paramMap.setMsgType("6");
        int getGiftTimes = 0;
        List<TableCountDO> getGiftList = imMsgDOMapper.count(paramMap);
        for (TableCountDO item: getGiftList){
            getGiftTimes = getGiftTimes + item.getTotal();
        }
        // 收礼人数
        Set<Integer> giftUserSet = new HashSet();
        List<ImMsgDO> giftUserList = imMsgDOMapper.getGiftUsers(paramMap);
        for(ImMsgDO item: giftUserList) {
            giftUserSet.add(item.getFromUser());
        }
        int getGiftUsers = giftUserSet.size();

        return new BaseRsp(ResultEnum.SUCCESS, new ImmutableMap.Builder<String, Object>().
                put("voiceTime", voiceTime).
                put("videoTime", videoTime).
                put("voiceConnTimes", voiceConnTimes).
                put("videoConnTimes", videoConnTimes).
                put("voiceConnUsers", Math.max(voiceConnUsers, 0)).
                put("videoConnUsers", Math.max(videoConnUsers, 0)).
                put("voiceGetTimes", voiceGetTimes).
                put("videoGetTimes", videoGetTimes).
                put("voiceGetUsers", Math.max(voiceGetUsers, 0)).
                put("videoGetUsers", Math.max(videoGetUsers, 0)).
                put("voiceSendTimes", voiceSendTimes).
                put("videoSendTimes", videoSendTimes).
                put("voiceSendConn", voiceSendConn).
                put("videoSendConn", videoSendConn).
                put("getGiftUsers", getGiftUsers).
                put("getGiftTimes", getGiftTimes).
                put("hiTimes", hiTimes).
                build()
        );
    }

    public BaseRsp userChatGiftList(VideoVoiceListDTO paramMap){
        if (!StringUtils.isEmpty(paramMap.getScene())) {
            String[] types = paramMap.getScene().split(",");
            paramMap.setScenes(Arrays.stream(types).map(Integer::parseInt).collect(Collectors.toList()));
        }
        List<ChatRecordDO> list = chatRecordDOMapper.list(paramMap);
        int count = chatRecordDOMapper.count(paramMap);
        return new BaseRsp(ResultEnum.SUCCESS, ImmutableMap.of( "list", list, "total", count));
    }

    public static void main(String[] args) {
    }

    @Override
    public BaseRsp cancelLive(String userId){
        String url= UrlConstant.ApiServerHost+"/user/cancelLiveCertification";
        JSONObject req = new JSONObject();
        req.put("userId", userId);
        String body= HttpInvokeUtil.httpPostJson(url, JSONObject.toJSONString(req), UrlConstant.DefaultEncode, null);
        BaseRsp rsp= JSONObject.parseObject(body, BaseRsp.class);
        return  rsp;
    }

    @Override
    public BaseRsp confirmAnchor(String userId){
        String url= UrlConstant.ApiServerHost+"/user/confirmAnchor";
        JSONObject req = new JSONObject();
        req.put("userId", userId);
        String body= HttpInvokeUtil.httpPostJson(url, JSONObject.toJSONString(req), UrlConstant.DefaultEncode, null);
        BaseRsp rsp= JSONObject.parseObject(body, BaseRsp.class);
        return  rsp;
    }

}
